package com.lzp.java.concurrent.lock.spinlock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 测试自旋锁
 *
 * @author lzp
 * @date 2020/04/19
 */
public class SpinLock {
    private static AtomicReference<Thread> spin = new AtomicReference<>();

    public void lock() {
        Thread currentThread = Thread.currentThread();
        // 不断CAS尝试设置原子引用
        while (!spin.compareAndSet(null, currentThread)) {
            System.out.println("获取自旋锁失败再次尝试！");
        }
    }

    public void unlock() {
        Thread currentThread = Thread.currentThread();
        // 将原子引用设为null
        spin.compareAndSet(currentThread, null);
    }

    public static void main(String[] args) {
        SpinLock spinLock = new SpinLock();
        Runnable task = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "开始尝试获取自旋锁...");
                spinLock.lock();
                System.out.println(Thread.currentThread().getName() + "已经获取到自旋锁...");

                try {
                    TimeUnit.MILLISECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    spinLock.unlock();
                }
            }
        };

        new Thread(task).start();
        new Thread(task).start();

    }

}
